package com.bilibili.dubbo.api;

import com.bilibili.dubbo.api.mongo.CommentApi;
import com.bilibili.model.enums.CommentType;
import com.bilibili.model.mongo.Comment;
import com.bilibili.model.mongo.Movement;
import com.bilibili.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

/**
 * @author HuangRongFu
 * 2021/11/22 星期一6:06 下午
 */

@DubboService
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发布评论 点赞 喜欢
     *
     * @param: comment
     */
    @Override
    public Integer add(Comment comment) {

        //获取了一条动态信息
        Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);

        //通过动态信息获取被评论人的id
        comment.setPublishUserId(movement.getUserId());

        //获取当前系统时间
        comment.setCreated(System.currentTimeMillis());

        //添加评论
        mongoTemplate.insert(comment);

        //更新动态的评论数
        Query query = new Query(Criteria.where("_id").is(comment.getPublishId()));

        Update update = new Update();

        update.inc(getCollName(comment.getCommentType()), 1);

        FindAndModifyOptions fmo = new FindAndModifyOptions();

        fmo.returnNew(true);//需要返回最新值

        movement = mongoTemplate.findAndModify(query, update, fmo, Movement.class);

        return movement.staticsCount(comment.getCommentType());
    }

    /**
     * 查看评论列表
     *
     * @param: page
     * @param: pageSize
     * @param: movementId
     * @Return: ResponseEntity
     */
    @Override
    public PageResult findPageByComment(Long page, Long pageSize, String movementId) {

        Query query = new Query(Criteria.where("publishId").is(new ObjectId(movementId)).and("commentType")
                            .is(CommentType.COMMENT.getType()));

        long total = mongoTemplate.count(query, Comment.class);

        long start = (page -1 ) * pageSize;

        List<Comment> commentList = new ArrayList<>();
        if(total > start){

            query.skip(start).limit(pageSize.intValue()).with(Sort.by(Sort.Order.desc("created")));

             commentList = mongoTemplate.find(query, Comment.class);

        }

        return  new PageResult(page, pageSize, total, commentList);
    }

    /**
     * 动态 取消点赞
     * @param:  movementId
     * @Return: ResponseEntity
     */
    @Override
    public Integer remove(Comment comment) {

        Query commentQuery = new Query(Criteria.where("userId").is(comment.getUserId())
                .and("publishId").is(comment.getPublishId())
                .and("commentType").is(getCollName(comment.getCommentType())));

        mongoTemplate.remove(commentQuery,Comment.class);

        //更新动态数量
        Query movementQuery = new Query(Criteria.where("_id").is(comment.getPublishId()));

        Update update = new Update();

        update.inc(getCollName(comment.getCommentType()), -1);
        FindAndModifyOptions fmo = new FindAndModifyOptions();

        fmo.returnNew(true);

        Movement newMovement = mongoTemplate.findAndModify(movementQuery, update, fmo, Movement.class);

        return newMovement.staticsCount(comment.getCommentType());
    }

    /**
     * 通过评论类型，获取要更新的动态表中的列名
     *
     * @return
     * @param: commentType
     */
    private String getCollName(int commentType) {
        if (CommentType.LIKE.getType() == commentType) {
            return "likeCount";
        } else if (CommentType.COMMENT.getType() == commentType) {
            return "commentCount";
        } else {
            return "loveCount";
        }
    }

}
